/**
 * 对公众平台发送给公众账号的消息加解密示例代码.
 *
 * @copyright Copyright (c) 1998-2014 Tencent Inc.
 */

// ------------------------------------------------------------------------

package com.chart.common.utils.wechat;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONException;
import com.alibaba.fastjson2.JSONObject;
import com.chart.common.constant.Constants;
import com.chart.common.core.redis.RedisCache;
import com.chart.common.exception.AesException;
import com.chart.common.exception.CustomAesException;
import com.chart.common.utils.http.HttpUtils;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.springframework.web.client.RestTemplate;

import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * SHA1 class
 *
 * 计算公众平台的消息签名接口.
 */
public class WeChatUtils {

    private static final String access_token = "access_token: ";

    private static final String grant_type = "client_credential";
    private static final String appId = "wx1e73641cc7528a1c";
    private static final String appSecre = "01aece16ec2576524da629ef3d52dace";


    private static final String aeskey = "aQ75LHE67D7Y7yE5Z4W77wJOW61yHfHEj88huqH8P4E";
    private static final String token = "ZtUXauT04mwUm20RJwuyiYZooyZM4uA7";

    private static final String accessTokenUrl = "https://api.weixin.qq.com/cgi-bin/token";

    private static final String ticketUrl = "https://api.weixin.qq.com/cgi-bin/qrcode/create";

    private static final String qrCodeUrl = "https://mp.weixin.qq.com/cgi-bin/showqrcode";

    private static final String loginCode = "{\"expire_seconds\": 180, \"action_name\": \"QR_STR_SCENE\", \"action_info\": {\"scene\": {\"scene_str\": \"login\"}}}";

    private static final String bindCode = "{\"expire_seconds\": 180, \"action_name\": \"QR_STR_SCENE\", \"action_info\": {\"scene\": {\"scene_str\": \"bind\"}}}";

    private static final String forwardCode = "{\"expire_seconds\": 180, \"action_name\": \"QR_STR_SCENE\", \"action_info\": {\"scene\": {\"scene_str\": \"forward\"}}}";

    private static Map<Integer, String> qrcode = new HashMap<>();

    static {
        qrcode.put(1, loginCode);
        qrcode.put(2, bindCode);
        qrcode.put(3, forwardCode);
    }

    /**
     * 用SHA1算法生成安全签名
     * @param token 票据
     * @param timestamp 时间戳
     * @param nonce 随机字符串
     * @param encrypt 密文
     * @return 安全签名
     * @throws AesException
     */
    public static String getSHA1(String token, String timestamp, String nonce, String encrypt) throws AesException {
        try {
            String[] array = new String[]{token, timestamp, nonce, encrypt};
            StringBuffer sb = new StringBuffer();
            // 字符串排序
            Arrays.sort(array);
            for (int i = 0; i < 4; i++) {
                sb.append(array[i]);
            }
            String str = sb.toString();
            // SHA1签名生成
            MessageDigest md = MessageDigest.getInstance("SHA-1");
            md.update(str.getBytes());
            byte[] digest = md.digest();

            StringBuffer hexstr = new StringBuffer();
            String shaHex = "";
            for (int i = 0; i < digest.length; i++) {
                shaHex = Integer.toHexString(digest[i] & 0xFF);
                if (shaHex.length() < 2) {
                    hexstr.append(0);
                }
                hexstr.append(shaHex);
            }
            return hexstr.toString();
        } catch (Exception e) {
            e.printStackTrace();
            throw new AesException(AesException.ComputeSignatureError);
        }
    }


    public static String getAccessToken() throws CustomAesException {
        String accessToken = HttpUtils.sendSSLGet(accessTokenUrl, "grant_type=" + grant_type + "&appid=" + appId + "&secret=" + appSecre, Constants.UTF8);
        return accessToken;
    }


    public static String getAccessTokenA() throws CustomAesException {
        // 获取完整的 access_token JSON 响应
        String jsonResponse = HttpUtils.sendSSLGet(
                accessTokenUrl,
                "grant_type=" + grant_type + "&appid=" + appId + "&secret=" + appSecre,
                Constants.UTF8
        );

        try {
            // 解析 JSON 响应
            JSONObject jsonObject = JSONObject.parseObject(jsonResponse);
            String accessToken = jsonObject.getString("access_token");

            if (accessToken == null || accessToken.isEmpty()) {
                throw new RuntimeException("未能成功提取 access_token: " + jsonResponse);
            }

            // 打印日志以调试
            System.out.println("提取的 access_token: " + accessToken);

            return accessToken; // 返回纯 access_token 字符串
        } catch (Exception e) {

        }
        return jsonResponse;
    }







    public static Map getTicket(Integer code, RedisCache redisCache){
        String accessToken = null;
        try {
            if (ObjectUtils.isEmpty(redisCache.getCacheObject(access_token)) ) {
                accessToken = getAccessToken();
                redisCache.setCacheObject(access_token,accessToken,7200, TimeUnit.SECONDS);
            }else {
                long expire = redisCache.getExpire(access_token);
                if (expire<=600) {
                    accessToken = getAccessToken();
                    redisCache.setCacheObject(access_token,accessToken,7200, TimeUnit.SECONDS);
                }else {
                    accessToken =redisCache.getCacheObject(access_token).toString();
                }
            }
        } catch (CustomAesException e) {
            e.printStackTrace();
        }
        JSONObject jsonObject = JSON.parseObject(accessToken);
        String access_token = jsonObject.get("access_token").toString();
        String json = qrcode.get(code);

        String tickets = null;
        try {
            tickets = HttpUtils.sendSSLPostP(ticketUrl + "?access_token=" + access_token, json);
        } catch (IOException e) {
            e.printStackTrace();
        }
        HashMap<String, Object> map = new HashMap<>();
        JSONObject jsonObject1 = JSON.parseObject(tickets);
        String ticket = jsonObject1.get("ticket").toString();

        System.out.println("我获取到的ticket"+ticket);
        String ticket_Url=qrCodeUrl+"?ticket="+ticket;
        map.put("ticket",ticket);
        map.put("expire_seconds",180);
        map.put("ticket_Url",ticket_Url);
        return map;
    }


}
